import { NFTStorage, File } from "nft.storage";
import { StandardMerkleTree } from "@openzeppelin/merkle-tree";

const key =
  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkaWQ6ZXRocjoweGIxYmEyN2I0NTM2NDAyYzZiMzJjNTg0NzdDNzREZkYzNjE5YTI4NTkiLCJpc3MiOiJuZnQtc3RvcmFnZSIsImlhdCI6MTcwOTE1NzM2Nzg1NywibmFtZSI6IkxveG9ORlQifQ.C9rggWbGPLJjza9iIYqJLvicJa0E4qHu09uiigtysqE";

export const creatMerkleTree = (values: any) => {
  const tree = StandardMerkleTree.of(values, ["address", "uint256"]);
  return {
    data: tree.dump(),
    rootHex: tree.root,
  };
};

export const uploadToIPFS = async (data: any, apiKey: string = key) => {
  const client = new NFTStorage({ token: apiKey });

  const blob = new Blob([JSON.stringify(data)], { type: "application/json" });
  const file = new File([blob], "winnersList.json", { type: "application/json" });
  const metadata = await client.storeBlob(file);

  return {
    cid: metadata,
    url: `https://${metadata}.ipfs.nftstorage.link`,
  };
};

function fetchIPFS(url: string) {
  return fetch(url)
    .then((res) => res.json())
    .then((res) => {
      return res;
    })
    .catch((e) => {
      // eslint-disable-next-line no-console
      console.error(e);
      throw e;
    });
}

export const getIPFS = async (url: string) => {
  const ipfs = sessionStorage.getItem("ipfs");

  if (ipfs && JSON.parse(ipfs).url === url) {
    const data = JSON.parse(ipfs).data;
    return data;
  }

  const data = await fetchIPFS(url);

  sessionStorage.setItem(
    "ipfs",
    JSON.stringify({
      url,
      data,
    })
  );

  return data;
};

export const getMerkleTreeValueByAccount = (data: any, account: any) => {
  const address = account?.toLocaleLowerCase() || account;
  const obj = {
    value: "",
    proof: [],
  };
  // load tree
  const tree = StandardMerkleTree.load(data);

  // get proof and amount
  for (const [i, v] of tree.entries()) {
    // 根据地址查询 用户总发放值 与 用户的proof
    if (v[0] == address || v[0] == account) {
      obj.value = v[1];
      obj.proof = tree.getProof(i) as any;
    }
  }
  return obj;
};

export const getShareRation = (val: any, total: any) => {
  if (total == 0) return "0.0000";
  return Number((val / Number(total)) * 100);
};

export interface ConfigType {
  epochStartTime: string | number;
  epochEndTime: string | number;
  LiquidityRate: number;
  TradingRate: number;
  ReferralRate: number;
  ProfitRate: number;
  AirdropTotal: number;
  SwapRate: number;
}

export interface ListType {
  account: any;
  share: number;
  reward: number;
  point: number;
}

export interface AirdropCheckData {
  list: ListType[];
  total: number;
}

export const getAirdropConfig = () => {
  const configUrl =
    "https://raw.githubusercontent.com/ModeMaxIO/ModeMax-Materials/main/config/airdrop.json?" + new Date().getTime();
  return fetch(configUrl)
    .then((res) => res.json())
    .then((res) => {
      return res;
    })
    .catch((e) => {
      // eslint-disable-next-line no-console
      console.error(e);
      throw e;
    });
};
